package com.jxpanda.infrastructure.crypto.toolkit;

import com.jxpanda.infrastructure.crypto.constant.AlgorithmEncrypt;

import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;

public class IvKit {

    /**
     * 生成指定长度的随机 IV
     *
     * @param length iv 字节长度（AES:16, DES:8）
     * @return IvParameterSpec
     */
    public static byte[] generateIvBytes(int length) {
        byte[] ivBytes = new byte[length];
        new SecureRandom().nextBytes(ivBytes);
        return ivBytes;
    }

    /**
     * 生成指定长度的随机 IV
     *
     * @param length iv 字节长度（AES:16, DES:8）
     * @return IvParameterSpec
     */
    public static IvParameterSpec generateIv(int length) {
        return new IvParameterSpec(generateIvBytes(length));
    }

    /**
     * 生成 AES（128-bit block）的随机 IV（16 字节）
     */
    public static byte[] generateAesIvBytes() {
        return generateIvBytes(AlgorithmEncrypt.AES.IV_LENGTH);
    }

    /**
     * 生成 AES（128-bit block）的随机 IV（16 字节）
     */
    public static IvParameterSpec generateAesIv() {
        return generateIv(AlgorithmEncrypt.AES.IV_LENGTH);
    }

    /**
     * 生成 DES（64-bit block）的随机 IV（8 字节）
     */
    public static byte[] generateDesIvBytes() {
        return generateIvBytes(AlgorithmEncrypt.DES.IV_LENGTH);
    }

    /**
     * 生成 DES（64-bit block）的随机 IV（8 字节）
     */
    public static IvParameterSpec generateDesIv() {
        return generateIv(AlgorithmEncrypt.DES.IV_LENGTH);
    }

    /**
     * 对齐 IV 到指定长度：过长则截断，不足则用 0 补齐。
     *
     * @param iv           原始 IV（可为 null，等同于空数组）
     * @param targetLength 目标字节长度（AES=16，DES=8）
     * @return IvParameterSpec 对齐后的 IV
     */
    public static byte[] alignIv(byte[] iv, int targetLength) {
        byte[] aligned = new byte[targetLength];
        if (iv != null) {
            // 截断或复制全部
            System.arraycopy(iv, 0, aligned, 0, Math.min(iv.length, targetLength));
        }
        // 剩余部分保持为 0x00
        return aligned;
    }

    public static byte[] alignAesIv(byte[] iv) {
        return alignIv(iv, AlgorithmEncrypt.AES.IV_LENGTH);
    }

    public static byte[] alignDesIv(byte[] iv) {
        return alignIv(iv, AlgorithmEncrypt.DES.IV_LENGTH);
    }

}
